﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ForeDelFile
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 2)
            {
                if (args[0] == "-f")
                {
                    if (File.Exists(args[1]))
                    {
                        try
                        {
                            File.Delete(args[1]);
                        }
                        catch (Exception)
                        {
                            ForceDelFile(args[1]);
                        }
                    }
                }

                if (args[0] == "-d")
                {
                    ForeDelDir(args[1]);
                }
            }
            
        }

        private static void ForceDelFile(string fileName)
        {

            if (System.IO.File.Exists(fileName))
            {
                using (Process handle = new Process())
                {
                    handle.StartInfo.FileName = "handle.exe";
                    handle.StartInfo.Arguments = $"\"{fileName}\" /accepteula";
                    handle.StartInfo.UseShellExecute = false;
                    handle.StartInfo.RedirectStandardOutput = true;
                    handle.Start();
                    handle.WaitForExit();
                    string outputTool = handle.StandardOutput.ReadToEnd();

                    string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
                    foreach (System.Text.RegularExpressions.Match match in System.Text.RegularExpressions.Regex.Matches(outputTool, matchPattern))
                    {
                        Process.GetProcessById(int.Parse(match.Value)).Kill();
                    }

                    System.Threading.Thread.Sleep(1000);

                    System.IO.File.Delete(fileName);
                }
            }
        }

        private static void ForeDelDir(string path)
        {
            if (System.IO.Directory.Exists(path))
            {
                foreach (var file in System.IO.Directory.GetFiles(path))
                {
                    try
                    {
                        System.IO.File.Delete(file);
                    }
                    catch (Exception)
                    {
                        ForceDelFile(file);
                    }
                }

                System.Threading.Thread.Sleep(1000);
                try
                {
                    System.IO.Directory.Delete(path, true);
                }
                catch (Exception)
                {

                    using (Process handle = new Process())
                    {
                        handle.StartInfo.FileName = "handle.exe";
                        handle.StartInfo.Arguments = $"\"{path}\" /accepteula";
                        handle.StartInfo.UseShellExecute = false;
                        handle.StartInfo.RedirectStandardOutput = true;
                        handle.Start();
                        handle.WaitForExit();
                        string outputTool = handle.StandardOutput.ReadToEnd();

                        string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
                        foreach (System.Text.RegularExpressions.Match match in System.Text.RegularExpressions.Regex.Matches(outputTool, matchPattern))
                        {
                            try
                            {
                                Process.GetProcessById(int.Parse(match.Value)).Kill();
                            }
                            catch (Exception ex)
                            {
                                var xxx = ex.Message;
                            }
                        }

                        System.Threading.Thread.Sleep(1000);

                        System.IO.Directory.Delete(path, true);
                    }
                }
            }
        }
    }
}
